package ran.youling.service.impl.impl;


import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import ran.youling.mapper.UserMapper;
import ran.youling.pojo.User;
import ran.youling.service.impl.UserService;

import ran.youling.util.JwtUtils;
import ran.youling.util.Result;
import ran.youling.vo.LoginUser;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


/**
 * @author Administrator
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2025-01-12 09:43:59
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {


    // 注入认证过滤器
    @Autowired
    private AuthenticationManager authenticationManager;
    //    redis
    @Autowired
    private StringRedisTemplate redisTemplate;
    //用于密码加密
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Result<Map<String, String>> login(User user) {
//把username和password等方法传递给security
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
//        注入认证过滤器 开始认证
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
// 输出结果：       UsernamePasswordAuthenticationToken [Principal=LoginUser(user=User(id=1, username=mengshujun, password=$2a$10$GysmSivtPRPPdT83CIgEGuusDd5soUIP275MdNjUmpuq.thg/YWxm, enabled=1)), Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]

        if (Objects.isNull(authentication)) {
            throw new UsernameNotFoundException("账号密码有误");
        }
//        使用构造传递给LoginUser实体类
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId().toString();//用于redisKey的唯一标识
//        封装token
        JSONObject from = JSONObject.from(loginUser);
        String token = JwtUtils.generateJwt(from);
//保存到redis并设置过期时间
        redisTemplate.opsForValue().set("login:" + userId, token, 2, TimeUnit.HOURS);//2,小时过期

        HashMap<String, String> stringHashMap = new HashMap<>();
        stringHashMap.put("token", token);
        return Result.success(stringHashMap);
    }


    @Override
    public String enroll(User user) {
//        调用passwordEncoder.encode进行密码加密，框架默认验证加密密码。
        String encode = passwordEncoder.encode(user.getPassword());
        User userOverride = new User();
        userOverride.setUsername(user.getUsername());
        userOverride.setPassword(encode);
        baseMapper.insert(userOverride);
        System.out.println("密码加密后：" + encode);
        return encode;
    }
}




